package com.zjcode.cdcer.service.impl;

import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import com.chinatechstar.component.commons.entity.MPage;
import com.chinatechstar.component.commons.result.PaginationBuilder;
import com.chinatechstar.component.commons.service.AliyunOssService;
import com.chinatechstar.component.commons.service.BaseService;
import com.chinatechstar.component.commons.supports.PageData;
import com.chinatechstar.component.commons.utils.ExcelUtils;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.zjcode.cdcer.mapper.TaskAssignmentMapper;
import com.zjcode.cdcer.mapper.TkmSysOrgMapper;
import com.zjcode.cdcer.mapper.TkmSysUserMapper;
import com.zjcode.cdcer.model.*;
import com.zjcode.cdcer.model.basic.JsonObj;
import com.zjcode.cdcer.service.CerSysteminitImportInfoService;
import com.zjcode.cdcer.service.SysDictService;
import com.zjcode.cdcer.service.TaskAssignmentService;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author ZQM
 * @date 2023/9/18 17:36
 */
@Service
public class TaskAssignmentServiceImpl implements TaskAssignmentService, BaseService {

    @Autowired
    private TaskAssignmentMapper taskAssignmentMapper;

    @Autowired
    private TkmSysOrgMapper tkmSysOrgMapper;

    @Autowired
    private TkmSysUserMapper userMapper;

    @Autowired
    private SysDictService sysDictService;

    @Autowired
    private CerSysteminitImportInfoService cerSysteminitImportInfoService;

    @Value("${studio.cer-personinfo-file-in-disk}")
    private String cerPersonFileInDisk;

    @Autowired
    private AliyunOssService aliyunOssService;
    @Override
    public JsonObj add(TaskAssignment taskAssignment) {
        // 2023-12-08更改，如果该机构已经分配完成，不允许再次分配
        if (taskAssignmentMapper.selectByInstitutionId(taskAssignment.getInstitutionId()) != 0) {
            return JsonObj.error("该机构已经完成分配");
        }
        // 主键id插入
        taskAssignment.setId(get32UUID());
        // 根据机构id查询整机构数据
        TkmSysOrg sysOrg = tkmSysOrgMapper.selectByPrimaryKey(Long.valueOf(taskAssignment.getInstitutionId()));
        // 区域列表及组级列表插入
        taskAssignment.setAncestors(sysOrg.getAncestors() + "," + sysOrg.getId());
        taskAssignment.setRegionCode(sysOrg.getRegionAncestors());
        Integer i = taskAssignmentMapper.add(taskAssignment);
        if (i > 0) {
            return JsonObj.success("创建成功");
        } else {
            return JsonObj.error("创建失败");
        }
    }

    @Override
    public JsonObj del(String id) {
        Integer i = taskAssignmentMapper.del(id);
        if (i > 0) {
            return JsonObj.success("删除成功");
        } else {
            return JsonObj.error("删除失败");
        }
    }

    @Override
    public JsonObj edit(TaskAssignment taskAssignment) {
        // 查询所属机构是否修改
        TaskAssignment assignment = taskAssignmentMapper.selAssignmentById(taskAssignment.getId());
        if (!assignment.getInstitution().equals(taskAssignment.getInstitution())) {
            // 根据机构id查询整机构数据
            TkmSysOrg sysOrg = tkmSysOrgMapper.selectByPrimaryKey(Long.valueOf(taskAssignment.getInstitutionId()));
            // 区域列表及组级列表插入
            taskAssignment.setAncestors(sysOrg.getAncestors() + "," + sysOrg.getId());
            taskAssignment.setRegionCode(sysOrg.getRegionAncestors());
        }
        Integer i = taskAssignmentMapper.edit(taskAssignment);
        if (i > 0) {
            return JsonObj.success("修改成功");
        } else {
            return JsonObj.error("修改失败");
        }
    }

    @Override
    public Map<String, Object> selById(String id) {
        Map<String, Object> map = new HashMap<>();
        // 查询任务分配信息
        TaskAssignment assignment = taskAssignmentMapper.selAssignmentById(id);
        map.put("id", assignment.getId());
        map.put("province", assignment.getProvince());
        map.put("city", assignment.getCity());
        map.put("district", assignment.getDistrict());
        map.put("institution", assignment.getInstitution());
        map.put("regionCode", assignment.getRegionCode());
        map.put("ancestors", assignment.getAncestors());
        map.put("screeningYear", assignment.getScreeningYear());
        map.put("firstScreeningTaskVolume", assignment.getFirstScreeningTaskVolume());
        map.put("followTaskVolume", assignment.getFollowTaskVolume());
        map.put("yearTaskVolume", assignment.getYearTaskVolume());
        map.put("approvedDetectionRate", assignment.getApprovedDetectionRate());
        map.put("timeBegin", assignment.getTimeBegin());
        map.put("timeEnd", assignment.getTimeEnd());
        map.put("status", assignment.getStatus());
        map.put("createTime", assignment.getCreateTime());
        map.put("updateTime", assignment.getUpdateTime());
        map.put("provinceId", assignment.getProvinceId());
        map.put("cityId", assignment.getCityId());
        map.put("districtId", assignment.getDistrictId());
        map.put("institutionId", assignment.getInstitutionId());
        return map;
    }

    @Override
    public Map<String, Object> selList(PageData pageData) {
        // 获取当前用户信息
        Long userId = Long.valueOf(pageData.get("user").toString());
        TkmSysUser userInfo = userMapper.selectByPrimaryKey(userId);
        TkmSysOrg orgInfo = tkmSysOrgMapper.selectByPrimaryKey(userInfo.getOrgId());
        pageData.put("ancestors", orgInfo.getAncestors());
        // 解析分页参数
        MPage mPage = getPageInfo(pageData);
        Page<Object> page = PageHelper.startPage(mPage.getCurrentPage(), mPage.getPageSize());
        List<LinkedHashMap<String, Object>> list = taskAssignmentMapper.selList(pageData);
        return PaginationBuilder.buildResult(list,
                page.getTotal(),
                mPage.getCurrentPage(),
                mPage.getPageSize());
    }

    @Override
    public JsonObj changeStatus(String id,String status) {
        Integer i = taskAssignmentMapper.changeStatus(id,status);
        String msg = Objects.equals(status, "2")? "封库": "取消";
        if (i > 0) {
            return JsonObj.success(msg+"成功");
        } else {
            return JsonObj.error(msg + "失败");
        }
    }

    @Override
    public List<LinkedHashMap<String, Object>> queryAllExportDataBy(PageData pageData) {
        Object idsData = pageData.get("ids");
        Long userId = Long.valueOf(pageData.get("user").toString());
        TkmSysUser userInfo = userMapper.selectByPrimaryKey(userId);
        TkmSysOrg orgInfo = tkmSysOrgMapper.selectByPrimaryKey(userInfo.getOrgId());
        pageData.put("ancestors", orgInfo.getAncestors());
        List<String> idList = new ArrayList<>();
        if (idsData != null) {
            idList = Arrays.asList(String.valueOf(idsData).split("\\|"));
        }
        List<LinkedHashMap<String, Object>> list = taskAssignmentMapper.selByIdList(idList,pageData,idsData);
        // 查询数据自定并分组
        List<SysDict> allCerDicts = sysDictService.findAllCerDicts();
        Map<String, List<SysDict>> keyListMap = allCerDicts
                .stream()
                .collect(Collectors.groupingBy(SysDict::getDictType));
        keyListMap.entrySet().parallelStream().forEach(entry -> {
            // key
            String key = entry.getKey();
            List<SysDict> dicts = entry.getValue();
            list.parallelStream().forEach(item->{
                Object o = item.get(key);
                if (o!=null) {
                    Optional<SysDict> first = dicts.stream()
                            .filter(sysDict -> sysDict.getDictValue().equals(o.toString())).findFirst();
                    first.ifPresent(sysDict -> {
                        item.put(key, sysDict.getDictName());
                    });
                }
            });
        });
        return list;
    }

    @Override
    public JsonObj importGJData(MultipartFile file, HttpServletResponse response, String userId) {
        ImportParams params = new ImportParams();
        params.setTitleRows(0);
        File tmpfile =cerSysteminitImportInfoService.commonImportConfig(file,userId);
        // 解析excel
        List<TaskAssignment> list = ExcelImportUtil.importExcel(tmpfile, TaskAssignment.class, params);
        // 数据过滤,国家来源的数据默认都是正确的，仅过滤名称为null的
        list = list.stream().filter(each -> StringUtils.isNotEmpty(each.getInstitution())).collect(Collectors.toList());
        int count = 0;
        // 执行数据写入
        List<LinkedHashMap<String, Object>> failList =new ArrayList<>();
        if (!list.isEmpty()) {
            List<LinkedHashMap<String, Object>> orgList = tkmSysOrgMapper.listAllData(new PageData());
            list.forEach(item->{
                item.setId(get32UUID());
                item.setErrorFlag(2);
                item.setErrorMsg("系统中没有该机构");
                item.setTimeBegin(ObjectUtils.isEmpty(item.getTimeBegin())?null:item.getTimeBegin().trim().substring(0,10));
                item.setTimeEnd(ObjectUtils.isEmpty(item.getTimeEnd())?null:item.getTimeEnd().trim().substring(0,10));
                orgList.forEach(each->{
                    if (Objects.equals(each.get("org_name"),item.getInstitution().trim())) {
                        item.setProvinceId(each.get("province_code").toString().trim().substring(0,2));
                        item.setProvince(each.get("province_name").toString());
                        item.setCityId(ObjectUtils.isEmpty(each.get("city_code"))?"":each.get("city_code").toString().trim().substring(0,4));
                        item.setCity(ObjectUtils.isEmpty(each.get("city_name"))?"":each.get("city_name").toString());
                        item.setDistrictId(ObjectUtils.isEmpty(each.get("region_code"))?"":each.get("region_code").toString().trim());
                        item.setDistrict(ObjectUtils.isEmpty(each.get("region_name"))?"":each.get("region_name").toString().trim());
                        item.setInstitutionId(each.get("id").toString());
                        // 区域列表及组级列表插入
                        item.setAncestors(each.get("ancestors") + "," + each.get("id"));
                        item.setRegionCode(each.get("region_ancestors").toString());
                        item.setErrorFlag(1);
                        item.setCountrySource("1");
                    }
                });
            });

            list.stream().filter(each -> each.getErrorFlag()== 2 ).forEach(item ->{
                failList.add(getLinkedMapByList(item, item.getErrorMsg() ));
            });
            list = list.stream().filter(each -> each.getErrorFlag()==1).collect(Collectors.toList());
            // 保存
            if(!list.isEmpty()){
                count = taskAssignmentMapper.addBatchTasks(list);
            }
        }
        // 组装表头
        List<String> headList = Arrays.asList(
                "省份",
                "城市",
                "区县",
                "机构名称",
                "开始时间",
                "结束时间",
                "筛查年度",
                "任务量",
                "导入错误原因");
        try {
            // 导出
            if (!failList.isEmpty()) {
//                String s = ExcelUtils.downloadExcel(headList, failList, "导入失败数据导出", response, cerPersonFileInDisk);
                File downloadExcelFile = ExcelUtils.downloadExcelFile(headList, failList, "导入失败数据导出", response, cerPersonFileInDisk);
                String upload = aliyunOssService.upload(downloadExcelFile);
                HashMap<String,Object> res =new HashMap<>();
                res.put("errorFile", upload);
                String msg ="导入失败"+failList.size()+"条";
                if (count>0) {
                    msg += "，导入成功"+count+"条数据";
                }
                return JsonObj.success(res,msg);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return JsonObj.error("错误数据导出失败");
        }
        return JsonObj.success("导入成功"+count+"条数据");
    }

    private LinkedHashMap<String, Object> getLinkedMapByList(TaskAssignment item, String errorMsg) {
        LinkedHashMap<String, Object> map = new LinkedHashMap<>();
        map.put("province", item.getProvince());
        map.put("city", item.getCity());
        map.put("district", item.getDistrict());
        map.put("institution", item.getInstitution());
        map.put("timeBegin", item.getTimeBegin());
        map.put("timeEnd", item.getTimeEnd());
        map.put("screeningYear", item.getScreeningYear());
        map.put("yearTaskVolume", item.getYearTaskVolume());
        map.put("errorFlag",errorMsg);
        return map;
    }
}
